﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Reflection;
using ETRobocon.RaceTraking.GamePresentation;

using ETRoboConTrakingSystem;

namespace ETRobocon.RaceTraking.GameManagement
{
    /// <summary>
    /// RunnerMgmtUserControl.xaml の相互作用ロジック
    /// </summary>
    public partial class RunnerMgmtUserControl : UserControl, IRunnerStatusNotifier
    {
   //     private TurnMgmtUserControl _ownerPanel;
   //     public TurnMgmtUserControl OwnerPanel
   //     {
   //         set
   //         {
   //             _ownerPanel = value;
   //         }
   //         get
   //         {
   //             return _ownerPanel;
   //         }
   //     }

        private List<CheckMarkMgmtControl> checkMarkMgmgControls = new List<CheckMarkMgmtControl>();
        public List<CheckMarkMgmtControl> MyCheckMarkMgmtControls { get { return checkMarkMgmgControls; } }

        public ITimerCounter MainTimerCounter { set; get; }
        public IRaceTrackingPresentation PresentationMain { set; get; }

        public WSRunner.CourseName CourseName
        {
            get;
            set;
        }

        public WSRunner CurrentRunner
        {
            get { return this.Resources["targetRunner"] as WSRunner; }
        }

        private WSTurn _currentTurn;
        public WSTurn CurrentTurn
        {
            set { _currentTurn = value; }
        }

        private string _courseImageUri;
        public String CourseImageUri
        {
            get
            {
                return _courseImageUri;
            }
            set
            {
             //   _courseImageUri = "ETRobocon.RaceTraking.GameMgmt" + "." + value;

                System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();

                string source = this.GetType().Namespace+".Imgs" + "." + value;
                System.IO.Stream imgStream = myAssembly.GetManifestResourceStream(source);
                
             //   _courseImageUri = "pack://application:,,,/"+value;

        //        BitmapImage bi = new BitmapImage(imgStream);
                _courseImageUri = value;
                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                //bi.UriSource = new Uri(_courseImageUri, UriKind.Relative);
//                bi.UriSource = new Uri(_courseImageUri, UriKind.Relative);
                bi.StreamSource = imgStream;
                bi.EndInit();

                rectangleCourse.Fill = new ImageBrush(bi);

                //      brush.ImageSource = new BitmapImage(_courseImageUri);
            }
        }

 //       private UserControlPresentationMain _presentationMain;
 //       public UserControlPresentationMain PresentationMain
 //       {
 //           set
 //           {
 //               _presentationMain = value;
 //           }
 //       }
        private IRunnerStatus _pmRunnerStatus;
        public IRunnerStatus PMRunnerStatus
        {
            set
            {
                _pmRunnerStatus = value;
            }
        }

        public RunnerMgmtUserControl()
        {
            InitializeComponent();

            checkMarkMgmgControls.Add(CheckMark0);
            checkMarkMgmgControls.Add(CheckMark1);
            checkMarkMgmgControls.Add(CheckMark2);
            checkMarkMgmgControls.Add(CheckMark3);
            checkMarkMgmgControls.Add(CheckMark4);
            checkMarkMgmgControls.Add(CheckMark9);
            checkMarkMgmgControls.Add(CheckMark8);
            checkMarkMgmgControls.Add(CheckMark7);
            checkMarkMgmgControls.Add(CheckMark6);
            checkMarkMgmgControls.Add(CheckMark5);
        }

        private void buttonPost_Click(object sender, RoutedEventArgs e)
        {
            PostRunResult();
        }

        public void HiddenRunnerVisibleStatus()
        {
            _pmRunnerStatus.HiddenRunnerStatus();
        }

        public void PostRunResult()
        {
            var rm = new ETRoboConTrakingSystem.ETRoboConRM.ETRoboConRaceMgmtClient();
//            using (WSRaceMgmt.RaceMgmt rm = new WSRaceMgmt.RaceMgmt())
            {
                List<int> bsResults = new List<int>();
                foreach (WSBonusResult br in CurrentRunner.BonusResults)
                {
                    if (br.Cleared)
                    {
                        bsResults.Add(br.Spec.ID);
                    }
                }
                ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus status = ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.COMPLETED;
//                WSRaceMgmt.RunnerStatus status = WSRaceMgmt.RunnerStatus.COMPLETED;
                int runTime = CurrentRunner.RunTime;
                if (comboBoxRunnerStatus.SelectedItem.ToString().EndsWith("Retired"))
                {
                    status = ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.RETIRED; //WSRaceMgmt.RunnerStatus.RETIRED;
                    runTime = 1200;
                    CurrentRunner.RunTime = 1200;
                }
                else if (comboBoxRunnerStatus.SelectedItem.ToString().EndsWith("Obstructed"))
                {
                    status = ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.OBSTRUCTED; // WSRaceMgmt.RunnerStatus.OBSTRUCTED;
                    runTime = 1200;
                    CurrentRunner.RunTime = 1200;
                    _pmRunnerStatus.CurrentRunner.RunTime = "120.0";
                    bsResults.Clear();
                }
                else if (comboBoxRunnerStatus.SelectedItem.ToString().EndsWith("Declined"))
                {
                    status = ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.DECLINED;
                    runTime = 1200;
                    CurrentRunner.RunTime = 1200;
                    _pmRunnerStatus.CurrentRunner.RunTime = "1200";
                    bsResults.Clear();
                }
                int point;
//                if (status == WSRaceMgmt.RunnerStatus.COMPLETED || status == WSRaceMgmt.RunnerStatus.RETIRED)
                if (status == ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.COMPLETED || status == ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.RETIRED || status == ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.DECLINED)
                {
                    if (rm.NotifyRaceResult(out point, _currentTurn.ID, CurrentRunner.Team.ID, status, runTime, bsResults.ToArray()))// new Guid(_currentTurn.ID), new Guid(CurrentRunner.Team.ID), status, runTime, bsResults.ToArray(), out point))
                    {
                        CurrentRunner.RunPoint = point;
                        int temp = point;
                        if (point < 0)
                        {
                            temp = -point;
                        }
                        string showingTime = String.Format("{0}.{1}", (temp / 10), (temp % 10));
                        if (point < 0)
                        {
                            showingTime = "-" + showingTime;
                        }
                        _pmRunnerStatus.CurrentRunner.Point = showingTime;
                    }
                }
                //                else if (status == WSRaceMgmt.RunnerStatus.OBSTRUCTED)
                else if (status == ETRoboConTrakingSystem.ETRoboConRM.RunnerStatus.OBSTRUCTED)
                {
                    if (rm.NotifyObstructed(_currentTurn.ID, CurrentRunner.Team.ID, false)) // new Guid(_currentTurn.ID), new Guid(CurrentRunner.Team.ID), false))
                    {
                        CurrentRunner.RunPoint = 1200;
                        _pmRunnerStatus.CurrentRunner.Point = "120.0";
                    }
                }
            }
            rm.Close();
        }

        public void UpdatePMRunnerStatus(int point)
        {
            int temp = point;
            string showingTime = String.Format("{0}.{1}", (temp / 10), (temp % 10));
            if (point < 0)
            {
                showingTime = "-" + showingTime;
            }
            _pmRunnerStatus.CurrentRunner.Point = showingTime;

        }
        private void buttonGoal_Click(object sender, RoutedEventArgs e)
        {
            int runTime = MainTimerCounter.CurrentTime;
            // _presentationMain.TimeCountCurrentTime;

            NotifyRunnerGoaled(runTime);
        }

        private void NotifyRunnerGoaled(int runTime)
        {
            if (CurrentRunner.Status == WSRunner.RunnerStatus.Running)
            {
                CurrentRunner.RunTime = runTime;
                CurrentRunner.Status = WSRunner.RunnerStatus.Completed;
                string showingTime = GetRunningByShowFormat(runTime);
                _pmRunnerStatus.CurrentRunner.RunTime = showingTime;
                //     CurrentRunner.GetBonusResult("GG").Cleared = true;

            }
        }

        private static string GetRunningByShowFormat(int runTime)
        {
            string showingTime = String.Format("{0}.{1}", (runTime / 10), (runTime % 10));
            return showingTime;
        }

        public void NotifyGoaled(int tick)
        {
            NotifyRunnerGoaled(tick);
            _pmRunnerStatus.RunnerTimerCounter.Stop();
        //    _pmRunnerStatus.ResetRunnerTimerCounter();
//            _pmRunnerStatus.RunnerTimerCounter.CurrentTime = tick;
            _pmRunnerStatus.RunnerTimerCounter.SetCurrentCount(tick);
            _pmRunnerStatus.ShowRunnerStatus(@"完走!!おめでとうっ");
        }

        public void NotifyRetired(int tick)
        {
            if (CurrentRunner.Status == WSRunner.RunnerStatus.Running)
            {
                int notifiedTick = tick;
                CurrentRunner.Status = WSRunner.RunnerStatus.Retired;
                if (tick > 1200)
                {
                    tick = 1200;
                }
                CurrentRunner.RunTime = tick;
                _pmRunnerStatus.CurrentRunner.RunTime = GetRunningByShowFormat(CurrentRunner.RunTime);
                _pmRunnerStatus.RunnerTimerCounter.Stop();
    //            _pmRunnerStatus.ResetRunnerTimerCounter();
//                _pmRunnerStatus.RunnerTimerCounter.CurrentTime = tick;
                _pmRunnerStatus.RunnerTimerCounter.SetCurrentCount(1200);
                _pmRunnerStatus.ShowRunnerStatus(@"リタイヤ…残念!!");
            }
        }

        private void comboBoxRunnerStatus_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            WSRunner.RunnerStatus status= WSRunner.RunnerStatus.Ready;
            string selectedValue = comboBoxRunnerStatus.SelectedValue.ToString();
            if (selectedValue.EndsWith(WSRunner.RunnerStatus.Obstructed.ToString()))
            {
                status = WSRunner.RunnerStatus.Obstructed;
            }
            else if (selectedValue.EndsWith(WSRunner.RunnerStatus.Completed.ToString()))
            {
                status = WSRunner.RunnerStatus.Completed;
            }
            else if (selectedValue.EndsWith(WSRunner.RunnerStatus.Ready.ToString()))
            {
                status = WSRunner.RunnerStatus.Ready;
            }
            else if (selectedValue.EndsWith(WSRunner.RunnerStatus.Retired.ToString()))
            {
                status = WSRunner.RunnerStatus.Retired;
            }
            else if (selectedValue.EndsWith(WSRunner.RunnerStatus.Running.ToString()))
            {
                status = WSRunner.RunnerStatus.Running;
            }
            else if (selectedValue.EndsWith(WSRunner.RunnerStatus.Declined.ToString()))
            {
                status = WSRunner.RunnerStatus.Declined;
            }
            else
            {
            }

            if (status==WSRunner.RunnerStatus.Obstructed)
            {
                OnRunnerStatusChanged(status);
//                this.OwnerPanel.buttonTurnAgain.IsEnabled = true;
//                this.OwnerPanel.buttonTurnLast.IsEnabled = true;
//                this.OwnerPanel.buttonTurnDone.IsEnabled = false;
                _pmRunnerStatus.ShowRunnerStatus(@"え～ん、失格");
            }
            else if (status == WSRunner.RunnerStatus.Declined)
            {
                OnRunnerStatusChanged(status);
            }
            // この実装は不適切。イベントを使った方が結合が疎になる。
            // 変更する場合は、IRunnerStatusNotifierを利用のこと。
        }

        #region IRunnerStatusNotifier メンバ

        public event RunnerStatusChangedEventHandler RunnerStatusChanged;

        void OnRunnerStatusChanged(WSRunner.RunnerStatus status)
        {
            if (RunnerStatusChanged != null)
            {
                RunnerStatusChanged(this, new RunnerStatusChangedEventArgs(CourseName, status));
            }
        }
        #endregion

        private void ComboBoxDifficultPoints_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string selected = ComboBoxDifficultPoints.SelectedItem.ToString();
            int index = -1;
            string lastChar = selected.Substring(selected.Length - 1);
            int tmp = 0;
            if (int.TryParse(lastChar, out tmp))
            {
                index = tmp;
            }
            _pmRunnerStatus.DifficultPointStatus.ShowImage(index);
        }

        public void ResetDifficltPointStatus()
        {
            ComboBoxDifficultPoints.SelectedIndex = 0;
        }
        public void LoadImageToDifficultPointStatus(int index, object dpItem)
        {
            _pmRunnerStatus.DifficultPointStatus.LoadStatusItem(index, dpItem);
        }

        public void ActivateDifficultPointStatus()
        {
            var uc = _pmRunnerStatus.DifficultPointStatus as UserControl;
            uc.Visibility = System.Windows.Visibility.Visible;
            comboBoxRunnerStatus.Visibility = System.Windows.Visibility.Visible;
        }

        private void textBoxRunTime_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (PresentationMain != null)
            {
                string runTime10Str = textBoxRunTime.Text;
                int runTime10=0;
                if ((!string.IsNullOrWhiteSpace(runTime10Str)) && int.TryParse(runTime10Str, out runTime10))
                {
                    string runTime = (runTime10 / 10).ToString() + "." + (runTime10 % 10).ToString();
                    if (CourseName == WSRunner.CourseName.IN)
                    {

                        PresentationMain.UpdateInCourseRunnerTime(runTime);
                    }
                    else
                    {
                        PresentationMain.UpdateOutCOurseRunnerTime(runTime);
                    }
                }
            }
        }

        public void SetSpecialNotice(string statement)
        {
            if (statement == "course-a")
            {
                this.ComboBoxDifficultPoints.SelectedIndex = 1;
            }
            else
            {
                this.ComboBoxDifficultPoints.SelectedIndex = 2;
            }
        }
    }
}
